package com.template.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.template.dto.Meal;
import com.template.dto.User;
import com.template.mapper.CommentMapper;
import com.template.mapper.MealMapper;
import com.template.mapper.MessageMapper;
import com.template.mapper.UserMapper;
import com.template.properties.JwtProperties;
import com.template.result.PageBean;
import com.template.result.Result;
import com.template.service.UserService;
import com.template.utils.AliOssUtil;
import com.template.utils.JwtUtils;
import com.template.context.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MealMapper mealMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JwtProperties jwtProperties;

    private static final String USER_LIST_KEY = "USER:list";

    private static List<User> USER_LIST = null;

//    @Override
//    public void test() throws InterruptedException {
//        int current=1;
//        int size=10;
//        //从缓存中拿到分页数据
////        List<User> USERList = getUSERListByRedis(current, size);
//
////        if (USERList == null || USERList.size() == 0) {
//            log.info("当前缓存中无分页数据，当前页:" + current + ",页大小:" + size);
//            //从数据库中拿到分页数据
//        List<User> USERList = getUSERListByDataSource(current, size);
////        }
//        Map<String, Object> resultMap = new HashMap<>();
//        //计算当前总页数
//        int totalPage = (USER_LIST.size() + size - 1) / size;
//        resultMap.put("total", USER_LIST.size());
//        resultMap.put("data", USERList);
//        resultMap.put("pages", totalPage);
//        System.out.println(resultMap);
////        return null;
//    }
//    private List<User> getUSERListByRedis(int current, int size) {
//        log.info("从Redis取出商品信息列表，当前页:" + current + ",页大小:" + size);
//        // 计算总页数
//        int pages = pages(size);
//        // 起始位置
//        int start = current <= 0 ? 0 : (current > pages ? (pages - 1) * size : (current - 1) * size);
//        // 终止位置
//        int end = start+size-1;
//        List<User> list = redisTemplate.opsForList().range(USER_LIST_KEY, start, end);
//        List<User> USERList = list;
//        return USERList;
//    }
//
//    private List<User> getUSERListByDataSource(int current, int size) throws InterruptedException {
//        //模拟从DB查询需要300ms
////        Thread.sleep(300);
//        USER_LIST=userMapper.getListById();
//        log.info("从数据库取出商品信息列表，当前页:" + current + ",页大小:" + size);
//        // 计算总页数
//        int pages = pages(size);
//        // 起始位置
//        int start = current <= 0 ? 0 : (current > pages ? (pages - 1) * size : (current - 1) * size);
//        //数据缓存到redis中
//        redisTemplate.opsForList().rightPushAll(USER_LIST_KEY, USER_LIST);
//        //设置当前key过期时间为1个小时
//        redisTemplate.expire(USER_LIST_KEY,1000*60*60, TimeUnit.MILLISECONDS);
//        return USER_LIST.stream().skip(start).limit(size).collect(Collectors.toList());
//    }
//
//    private Integer pages(int size){
//        int pages = USER_LIST.size() % size == 0 ? USER_LIST.size() / size : USER_LIST.size() / size + 1;
//        return pages;
//    }



    @Override
    @Transactional//事务，要么都成功，要么都失败
    public Result add(User user) {
        String account=user.getAccount();
        Integer state=user.getState();
        User user1=userMapper.login(account,state);
//        System.out.println("user1"+user1);
        if(user1==null) {
            userMapper.add(user);
            System.out.println("新增的userId"+user.getId());

//            新增与该用户相对应的关系表meal表
            Meal meal=new Meal();
            meal.setTest(0);
            meal.setRichTextEditor(0);
            meal.setCrud(0);
            meal.setCssStyle(0);
            meal.setForum(0);
meal.setHome(1);
meal.setCommunity(0);
            meal.setNote(0);
            mealMapper.add(meal);

            mealMapper.mealAndUser(user.getId(),meal.getId());

            return Result.success();
        }
        return Result.error("该账号已存在，请换一个");
    }

    @Override
    public PageBean getList(Integer page, Integer pageSize){
        PageHelper.startPage(page,pageSize);

        List<User> userList =userMapper.getListById();
        Page<User> p =(Page<User>) userList;

        return new PageBean(p.getTotal(),p.getResult());
    }

    @Override
//    rollbackFor = Exception.class 表示任何类型的 Exception 都会触发事务回滚
//    isolation = Isolation.READ_COMMITTED 表示事务的隔离级别为 READ_COMMITTED
//    Isolation.READ_COMMITTED：不允许脏读，但允许不可重复读和幻读。
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void delById(Long userId) {
        try {
            //删除该用户oss中的图片
            User user =userMapper.getEditById(userId);
            String imgPath=user.getImageUrl();
            aliOssUtil.deleteFile(imgPath);

            // 删除user表中的数据
            userMapper.delById(userId);

            // 获取meal表中的mealId
            Long mealId = mealMapper.selectMealId(userId);

            // 检查mealId是否为null
            if (mealId == null) {
//                在获取 mealId 后，检查其是否为 null。如果是 null，则抛出一个 RuntimeException，这将触发事务回滚。
                throw new RuntimeException("mealId 等于 null, 将进行事务回滚");
            }
            // 删除meal表中的数据
            mealMapper.delById(mealId);

            // 删除mealanduser表中的数据
            userMapper.delMealAndUserById(userId);
        } catch (Exception e) {
            // 记录异常信息
            e.printStackTrace();
            // 重新抛出异常，让事务管理器处理回滚
            throw e;
        }
    }

    @Override
    public User getEditById(Long id) {
        return userMapper.getEditById(id);
    }

    @Override
    public Result editUserById(User user) {
        String account=user.getAccount();
        Integer state=user.getState();
        Long id=user.getId();
        User user1=userMapper.login(account,state);
        User user2=userMapper.getEditById(id);


        //判断账号是否唯一
        if(user1==null || Objects.equals(user1.getAccount(), user2.getAccount())) {
            Map<String,Object> claims=new HashMap<>();
            claims.put("id",user.getId());
            claims.put("name",user.getName());
            claims.put("account",user.getAccount());
            claims.put("imageUrl",user.getImageUrl());

            String jwt= jwtUtils.generateJwt(claims);

            userMapper.editUserById(user);
            messageMapper.editMessage(user);
            commentMapper.editComment(user);
//            BlacklistService blacklistService= SpringUtil.getBean(BlacklistService.class);
//            blacklistService.addToBlacklist(jwt);
            return Result.success(jwt);
        }

        System.out.println("该账号已存在，请换一个");
        return Result.error("该账号已存在，请换一个");
    }

    @Override
    public List<User> exportExcelUser() {
        List<User> exportUserList=userMapper.exportExcelUser();
        return exportUserList;
    }

    @Override
    public Result login(User user) {
        String account=user.getAccount();
        String password=user.getPassword();
        Integer state=user.getState();
        User user1=userMapper.login(account,state);
        if(user1 == null){
            return Result.error("账号或密码错误");
        }
        if(!user1.getPassword().equals(password)){
            return Result.error("账号或密码错误");
        }

        System.out.println(user1.getId());

        //记录登录信息
        User user2=new User();
        LocalDateTime loginTime=LocalDateTime.now();
        user2.setId(user1.getId());
        user2.setCreateTime(loginTime);
        user2.setAccount(user1.getAccount());
        user2.setName(user1.getName());
//        System.out.println()
        userMapper.loginLogs(user2);

        Map<String,Object> claims=new HashMap<>();
        claims.put("id",user1.getId());
        claims.put("name",user1.getName());
        claims.put("account",user1.getAccount());
        claims.put("imageUrl",user1.getImageUrl());
        claims.put("state",user1.getState());

//        UserContext.setCurrentUserId(user1.getId());
//        System.out.println("存入当前登录id"+UserContext.getCurrentUserId());


//System.out.println("进入"+claims);
        String jwt= jwtUtils.generateJwt(claims);
//        System.out.println("sdfsd"+jwt);
        return Result.success(jwt);
    }

}
